home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2001 / MacHack 2001.toast / pc / The Hacks / MacCleo / geoface / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-06-23  |  15.6 KB  |  614 lines

  1. /* aux2glut conversion Copyright (c) Mark J. Kilgard, 1997 */
  2.  
  3. /* ==========================================================================
  4.                                MAIN_C
  5. =============================================================================
  6.  
  7.     FUNCTION NAMES
  8.  
  9.     movelight         -- moves the light source.
  10.     rotatexface     -- rotates the face about the X axis.
  11.     rotateyface     -- rotates the face about the Y axis.
  12.     myinit         -- local initialization.
  13.     faceinit         -- glutInit(&argc, argv); initialize the face data.
  14.     display         -- display functions.
  15.     myReshape         -- window respahe callback.
  16.     error_exit        -- error function.
  17.     usage        -- usage function.
  18.     GLenum Key         -- keyboard mappings.
  19.     main         -- main program.
  20.  
  21.  
  22.     C SPECIFICATIONS
  23.  
  24.     void movelight     ( int x, int y )
  25.     void rotatexface     ( int x, int y )
  26.     void rotateyface     ( int x, int y )
  27.     void myinit     ( void )
  28.     faceinit         ( void )
  29.     void display     ( void )
  30.     void myReshape     ( GLsizei w, GLsizei h )
  31.     void error_exit    ( char *error_message )
  32.     void usage        ( char *name )
  33.     static GLenum Key     ( int key, GLenum mask )
  34.     void main         ( int argc, char** argv )
  35.  
  36.     DESCRIPTION
  37.     
  38.     This module is where everything starts.    This module comes as is 
  39.     with no warranties.  
  40.  
  41.     SIDE EFFECTS
  42.     Unknown.
  43.    
  44.     HISTORY
  45.     Created 16-Dec-94  Keith Waters at DEC's Cambridge Research Lab.
  46.     Modified 22-Nov-96 Sing Bing Kang (sbk@crl.dec.com)
  47.       Added function print_mesg to print out all the keyboard commands
  48.       Added the following functionalities:
  49.         rereading the expression file
  50.         changing the expression (based on the expression file)
  51.         quitting the program with 'q' or 'Q' in addition to 'Esc'
  52.  
  53. ============================================================================ */
  54.  
  55. #include <stdio.h>
  56. #include <string.h>
  57. #include <stdlib.h>
  58. #include <GLUT/glut.h>
  59.  
  60. #include "memory.h"               /* Local memory allocation macros          */
  61. /*#include "window.h"                Local window header                     */
  62. #include "head.h"                 /* Local head data structure               */
  63.  
  64. int verbose = 0;
  65.  
  66. void print_mesg(void);
  67.  
  68. int DRAW_MODE = 2 ;
  69.  
  70. HEAD *face ;
  71.  
  72. static int spinxlight = 0 ;
  73. static int spinylight = 0 ;
  74. static int spinxface = 0 ;
  75. static int spinyface = 0 ;
  76.  
  77. void card_guess();
  78. void embarrass_kiki();
  79.  
  80. /* ========================================================================= */
  81. /* motion                                                                 */
  82. /* ========================================================================= */  
  83. /*
  84. ** Rotate the face and light about.
  85. */
  86.  
  87. int rotate = 0, movelight = 0, origx, origy;
  88.  
  89. void motion ( int x, int y )
  90. {
  91.   if (rotate) {
  92.     spinyface = ( spinyface + (x - origx) ) % 360 ;
  93.     spinxface = ( spinxface + (y - origy) ) % 360 ;
  94.     origx = x;
  95.     origy = y;
  96.     glutPostRedisplay();
  97.   }
  98.   if (movelight) {
  99.     spinylight = ( spinylight + (x - origx ) ) % 360 ;
  100.     spinxlight = ( spinxlight + (y - origy ) ) % 360 ;
  101.     origx = x;
  102.     origy = y;
  103.     glutPostRedisplay();
  104.   }
  105. }
  106.  
  107. void
  108. mouse(int button, int state, int x, int y)
  109. {
  110.   switch(button) {
  111.   case GLUT_LEFT_BUTTON:
  112.     if (state == GLUT_DOWN) {
  113.       origx = x;
  114.       origy = y;
  115.       rotate = 1;
  116.     } else {
  117.       rotate = 0;
  118.     }
  119.     break;
  120.   case GLUT_MIDDLE_BUTTON:
  121.     if (state == GLUT_DOWN) {
  122.       origx = x;
  123.       origy = y;
  124.       movelight = 1;
  125.     } else {
  126.       movelight = 0;
  127.     }
  128.     break;
  129.   }
  130. }
  131.  
  132.  
  133. /* ========================================================================= */
  134. /* myinit                                                             */
  135. /* ========================================================================= */  
  136. /*
  137. ** Do the lighting thing.
  138. */
  139.  
  140. void myinit ( void )
  141. {
  142.   glEnable    ( GL_LIGHTING   ) ;
  143.   glEnable    ( GL_LIGHT0     ) ;
  144.   glDepthFunc ( GL_LEQUAL     ) ;
  145.   glEnable    ( GL_DEPTH_TEST ) ;
  146. }
  147.  
  148.  
  149. /* ========================================================================= */
  150. /* faceinit                                                             */
  151. /* ========================================================================= */  
  152. /*
  153. ** Read in the datafiles and glutInit(&argc, argv); initialize the face data structures.
  154. */
  155.  
  156. void
  157. faceinit ( void )
  158. {
  159.   face = create_face         ( "index.dat", "faceline.dat") ;
  160.   read_muscles               ("muscle.dat", face ) ;
  161.   read_expression_vectors    ("expression-vectors.dat", face ) ;
  162.   data_struct                ( face ) ;    
  163. }
  164.  
  165. void
  166. read_expressions(void)
  167. {
  168.   read_expression_vectors    ("expression-vectors.dat", face ) ;
  169. }
  170.  
  171. void
  172. dump_current_expression(void)
  173. {
  174.     int k;
  175.     for ( k=0; k < 17; k++) {
  176.       printf ( "%f ",  face->muscle[k]->mstat ) ;
  177.     }
  178.     printf ("\n") ;
  179. }
  180.  
  181. static
  182. void next_expression( int delta )
  183. {
  184.     static int    cur_expression;
  185.     cur_expression = cur_expression+delta;
  186.         if (cur_expression>face->nexpressions)
  187.             cur_expression = 0;
  188.         if (cur_expression<0) 
  189.             cur_expression = face->nexpressions;
  190.         
  191.     if (cur_expression==0) {
  192.             glutSetWindowTitle("default");
  193.             face_reset ( face ) ;
  194.     } else {
  195.             glutSetWindowTitle( face->expression[cur_expression-1]->name );
  196.             face_reset  ( face ) ;
  197.             expressions( face, cur_expression-1 );
  198.     }
  199.     glutPostRedisplay();
  200. }
  201.  
  202. /* ========================================================================= */
  203. /* display                                                                   */
  204. /* ========================================================================= */  
  205. /*
  206. ** Here's were all the display action takes place.
  207. */
  208.  
  209. void display ( void )
  210. {
  211.   GLfloat position [] = { 30.0, 70.0, 100.0, 1.0 }  ;
  212.     
  213.   glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
  214.  
  215.   glPushMatrix ( ) ; 
  216.   
  217.     glTranslatef ( 0.0, 0.0, -30.0 ) ;
  218.  
  219.     glRotated    ( (GLdouble) spinxface, 1.0, 0.0, 0.0 ) ;
  220.     glRotated    ( (GLdouble) spinyface, 0.0, 1.0, 0.0 ) ;
  221.   
  222.     glPushMatrix ( ) ; 
  223.       glRotated        ( (GLdouble) spinxlight, 1.0, 0.0, 0.0 ) ;
  224.       glRotated        ( (GLdouble) spinylight, 0.0, 1.0, 0.0 ) ;
  225.       glLightfv        ( GL_LIGHT0, GL_POSITION, position ) ;
  226.   
  227.       glTranslated     ( 0.0, 0.0, 50.0 ) ;
  228.       glDisable        ( GL_LIGHTING ) ;
  229.       glColor3f        ( 0.0, 1.0, 1.0 ) ;
  230.       glutWireCube     ( 0.1 ) ;
  231.       glEnable        ( GL_LIGHTING ) ;
  232.    glPopMatrix ( ) ;
  233.  
  234.   calculate_polygon_vertex_normal     ( face ) ;
  235.  
  236.   paint_polygons             ( face, DRAW_MODE, 0 ) ;    
  237.  
  238.   if ( DRAW_MODE == 0 )
  239.     paint_muscles            ( face ) ;
  240.   
  241.   glPopMatrix();
  242.  
  243.   glutSwapBuffers();
  244. }
  245.  
  246.  
  247. /* ========================================================================= */
  248. /* myReshape                                                             */
  249. /* ========================================================================= */  
  250. /*
  251. ** What to do of the window is modified.
  252. */
  253.  
  254. void myReshape ( GLsizei w, GLsizei h )
  255. {
  256.   glViewport    ( 0,0,w,h ) ;
  257.   glMatrixMode  ( GL_PROJECTION ) ;
  258.   glLoadIdentity( ) ;
  259.   gluPerspective( 40.0, (GLfloat) w/(GLfloat) h, 1.0, 100.0 ) ;
  260.   glMatrixMode  ( GL_MODELVIEW ) ;
  261. }
  262.  
  263.  
  264. /* ========================================================================= */
  265. /* error_exit                                                                 */
  266. /* ========================================================================= */  
  267. /*
  268. ** Problems!
  269. */
  270.  
  271. void error_exit( char *error_message )
  272. {
  273.     fprintf ( stderr, "%s\n", error_message ) ;
  274.     exit( 1 ) ;
  275. }
  276.  
  277.  
  278. /* ========================================================================= */
  279. /* usage                                                             */
  280. /* ========================================================================= */  
  281. /*
  282. ** At startup provide usage modes.
  283. */
  284.  
  285. void usage( char *name )
  286. {
  287.     fprintf( stderr, "\n%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
  288.         "usage: ", name, " [options]\n\n",
  289.         "  Options:\n",
  290.         "    -display  displayname  specify an X server connection\n",
  291.         "    -geometry geometry     specify window geometry in pixels\n",
  292.         "    -rgba                  ask for rgba visual\n",
  293.         "    -index                 ask for color index visual\n",
  294.         "    -doublebuffer          ask for double buffered visual\n",
  295.         "    -singlebuffer          ask for single buffered visual\n",
  296.         "    -accum                 ask for accumulation buffer\n",
  297.         "    -alpha                 ask for alpha buffer\n",
  298.         "    -depth                 ask for depth buffer\n",
  299.         "    -stencil               ask for stencil buffer\n",
  300.         "    -aux nauxbuf           specify number of aux buffers\n",
  301.         "    -level planes          specify planes (0=main,>0=overlay,<0=underlay\n",
  302.         "    -transparent           ask for transparent overlay\n",
  303.         "    -opaque                ask for opaque overlay\n"
  304.     );
  305.     
  306.     exit( 1);
  307. }
  308.  
  309. /* ========================================================================= */
  310. /* Key                                                                 */
  311. /* ========================================================================= */
  312. /*
  313. ** Actions on a key press.
  314. */
  315.  
  316. static int m = 0, e = 0;
  317.  
  318. /* ARGSUSED1 */
  319. static void Key ( unsigned char key, int x, int y )
  320. {
  321.   char title[512];
  322.   
  323.     switch ( key ) {
  324.       case 27 :
  325.       case 'q' :
  326.       case 'Q' :
  327.     exit (0) ;
  328.  
  329.       case 'r' :
  330.       case 'R' :
  331.     printf ("Rereading expression file\n");
  332.         read_expressions();
  333.     e = 0; /* reset the expression count variable */
  334.     glutPostRedisplay();
  335.     break;
  336.  
  337.       case 'a' :
  338.     printf ("increment muscle: %s\n", face->muscle[m]->name ) ;
  339.  
  340.     /* set the muscle activation */
  341.     face->muscle[m]->mstat += 0.1 ;
  342.     
  343.     activate_muscle ( face, 
  344.              face->muscle[m]->head, 
  345.              face->muscle[m]->tail, 
  346.              face->muscle[m]->fs,
  347.              face->muscle[m]->fe,
  348.              face->muscle[m]->zone,
  349.              0.1 ) ;
  350.     glutPostRedisplay();
  351.     break;
  352.  
  353.       case 'A' :
  354.     printf ("decrement muscle: %s\n", face->muscle[m]->name ) ;
  355.     face->muscle[m]->mstat -= 0.1 ;
  356.  
  357.     activate_muscle ( face, 
  358.              face->muscle[m]->head, 
  359.              face->muscle[m]->tail, 
  360.              face->muscle[m]->fs,
  361.              face->muscle[m]->fe,
  362.              face->muscle[m]->zone,
  363.              -0.1 ) ;
  364.     glutPostRedisplay();
  365.     break;
  366.  
  367.       case 'b' :
  368.     DRAW_MODE++ ;
  369.  
  370.     if ( DRAW_MODE >= 3 ) DRAW_MODE = 0 ;
  371.     printf ("draw mode: %d\n", DRAW_MODE ) ;
  372.     glutPostRedisplay();
  373.     break;
  374.  
  375.       case 'c' :
  376.     face_reset ( face ) ;
  377.     glutPostRedisplay();
  378.     break;
  379.     
  380.       case 'n' :
  381.     m++ ;
  382.     if ( m >= face->nmuscles ) m = 0 ;
  383.         sprintf(title, "geoface (%s)", face->muscle[m]->name);
  384.         glutSetWindowTitle(title);
  385.     break;
  386.  
  387.       case 'e' :
  388.     if (face->expression) {
  389.     face_reset  ( face ) ;
  390.     expressions ( face, e ) ;
  391.  
  392.     e++ ;
  393.     if ( e >= face->nexpressions ) e = 0 ;
  394.     glutPostRedisplay();
  395.     }
  396.     break;
  397.  
  398.       case 'h' :
  399.     
  400.     print_mesg();
  401.     
  402.     }
  403. }
  404.  
  405.  
  406. /* ARGSUSED1 */
  407. void
  408. special(int key, int x, int y)
  409. {
  410.   char title[512];
  411.  
  412.   switch(key) {
  413.   case GLUT_KEY_RIGHT:
  414.     m++ ;
  415.     if ( m >= face->nmuscles ) m = 0 ;
  416.     sprintf(title, "geoface (%s)", face->muscle[m]->name);
  417.     glutSetWindowTitle(title);
  418.     break;
  419.   case GLUT_KEY_LEFT:
  420.     m-- ;
  421.     if ( m < 0 ) m = face->nmuscles - 1 ;
  422.     sprintf(title, "geoface (%s)", face->muscle[m]->name);
  423.     glutSetWindowTitle(title);
  424.     break;
  425.   case GLUT_KEY_UP:
  426.     face->muscle[m]->mstat += 0.1 ;
  427.  
  428.     activate_muscle ( face, 
  429.              face->muscle[m]->head, 
  430.              face->muscle[m]->tail, 
  431.              face->muscle[m]->fs,
  432.              face->muscle[m]->fe,
  433.              face->muscle[m]->zone,
  434.              0.1 ) ;
  435.     glutPostRedisplay();
  436.     break;
  437.   case GLUT_KEY_DOWN:
  438.     face->muscle[m]->mstat -= 0.1 ;
  439.  
  440.     activate_muscle ( face, 
  441.              face->muscle[m]->head, 
  442.              face->muscle[m]->tail, 
  443.              face->muscle[m]->fs,
  444.              face->muscle[m]->fe,
  445.              face->muscle[m]->zone,
  446.              -0.1 ) ;
  447.     glutPostRedisplay();
  448.     break;
  449.     
  450.     case GLUT_KEY_F1:    dump_current_expression();            break;
  451.     case GLUT_KEY_F2:    read_expressions();            break;
  452.     case GLUT_KEY_F3:    next_expression( 1 );        break;
  453.     case GLUT_KEY_F4:    next_expression( -1 );        break;
  454.     case GLUT_KEY_F5:    card_guess();            break;
  455.     case GLUT_KEY_F6:    embarrass_kiki();        break;
  456.   }
  457. }
  458.  
  459.  
  460. /* ========================================================================= *
  461.  * print_mesg
  462.  * Written by: Sing Bing Kang (sbk@crl.dec.com)
  463.  * Date: 11/22/96
  464.  * ========================================================================= */
  465. /*
  466. ** Prints out help message
  467. */
  468. void
  469. print_mesg(void)
  470. {
  471. fprintf(stderr,"\n");
  472. fprintf(stderr,"a:       draw mode (to `pull' the current facial muscle)\n");
  473. fprintf(stderr,"A:       draw mode (to `contract' current facial muscle)\n");
  474. fprintf(stderr,"c:       face reset\n");
  475. fprintf(stderr,"n:       next muscle (to select another facial muscle to manipulate)\n");
  476. fprintf(stderr,"e:       next expression\n");
  477. fprintf(stderr,"b:       to change draw mode: wireframe->polygonal patches->smooth surface\n");
  478. fprintf(stderr,"r,R:     reread the expression file (../face-data/expression-vectors.dat)\n         (Note: this resets the expression sequence to the beginning)\n");
  479. fprintf(stderr,"q,Q,Esc: quit\n");
  480. fprintf(stderr,"h:       outputs this message\n");
  481. fprintf(stderr,"\n");
  482. }
  483.  
  484. void
  485. muscle_select(int value)
  486. {
  487.   char title[512];
  488.  
  489.   /* Select muscle. */
  490.   m = value;
  491.   sprintf(title, "geoface (%s)", face->muscle[m]->name);
  492.   glutSetWindowTitle(title);
  493. }
  494.  
  495. void
  496. main_menu_select(int value)
  497. {
  498.   char title[512];
  499.  
  500.   switch(value) {
  501.   case 1:
  502.     face_reset ( face ) ;
  503.     glutPostRedisplay();
  504.     break;
  505.   case 2:
  506.     print_mesg();
  507.     break;
  508.   case 3:
  509.     face->muscle[m]->mstat += 0.25 ;
  510.     activate_muscle ( face, 
  511.       face->muscle[m]->head, 
  512.       face->muscle[m]->tail, 
  513.       face->muscle[m]->fs,
  514.       face->muscle[m]->fe,
  515.       face->muscle[m]->zone,
  516.       +0.25 ) ;
  517.     glutPostRedisplay();
  518.     break;
  519.   case 4:
  520.     face->muscle[m]->mstat -= 0.25 ;
  521.     activate_muscle ( face, 
  522.       face->muscle[m]->head, 
  523.       face->muscle[m]->tail, 
  524.       face->muscle[m]->fs,
  525.       face->muscle[m]->fe,
  526.       face->muscle[m]->zone,
  527.       -0.25 ) ;
  528.     glutPostRedisplay();
  529.     break;
  530.   case 5:
  531.     m++ ;
  532.     if ( m >= face->nmuscles ) m = 0 ;
  533.     sprintf(title, "geoface (%s)", face->muscle[m]->name);
  534.     glutSetWindowTitle(title);
  535.     break;
  536.   case 666:
  537.     exit(0);
  538.     break;
  539.   }
  540. }
  541.  
  542. void
  543. draw_mode_select(int value)
  544. {
  545.   DRAW_MODE = value;
  546.   glutPostRedisplay();
  547. }
  548.  
  549. void
  550. make_menus(void)
  551. {
  552.   int i, j, muscle_menu, draw_mode_menu;
  553.   char *entry;
  554.  
  555.   muscle_menu = glutCreateMenu(muscle_select);
  556.   for (i=0; i<face->nmuscles; i++) {
  557.     entry = face->muscle[i]->name;
  558.     for(j=(int) strlen(entry)-1; j>=0; j--) {
  559.       if (entry[j] == '_') entry[j] = ' ';
  560.     }
  561.     glutAddMenuEntry(entry, i);
  562.   }
  563.   draw_mode_menu = glutCreateMenu(draw_mode_select);
  564.   glutAddMenuEntry("Wireframe", 0);
  565.   glutAddMenuEntry("Polygonal patches", 1);
  566.   glutAddMenuEntry("Smooth surface", 2);
  567.   glutCreateMenu(main_menu_select);
  568.   glutAddMenuEntry("Pull muscle up", 3);
  569.   glutAddMenuEntry("Pull muscle down", 4);
  570.   glutAddMenuEntry("Next muscle", 5);
  571.   glutAddSubMenu("Select muscle", muscle_menu);
  572.   glutAddSubMenu("Draw mode", draw_mode_menu);
  573.   glutAddMenuEntry("Face reset", 1);
  574.   glutAddMenuEntry("Print help", 2);
  575.   glutAddMenuEntry("Quit", 666);
  576.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  577. }
  578.  
  579. /* ========================================================================= */
  580. /* main                                                                */
  581. /* ========================================================================= */
  582. /*
  583. ** All the initialization and action takes place here.
  584. */
  585.  
  586. int main ( int argc, char** argv )
  587. {
  588.   int i;
  589.  
  590.   glutInitWindowSize    ( 400, 600 ) ;
  591.   glutInit(&argc, argv);
  592.   for(i=1; i<argc; i++) {
  593.     if(!strcmp(argv[i], "-v")) {
  594.       verbose = 1;
  595.     }
  596.   }
  597.   glutInitDisplayMode    (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_MULTISAMPLE);
  598.   glutCreateWindow        ( "geoface" ) ;
  599.   myinit        ( ) ;
  600.   faceinit        ( ) ;
  601.   glutMouseFunc(mouse);
  602.   glutMotionFunc(motion);
  603.   glutKeyboardFunc        ( Key ) ;    
  604.   glutSpecialFunc(special);
  605.   glutReshapeFunc     ( myReshape ) ;
  606.   glutDisplayFunc(display);
  607.   make_menus();
  608.   glutMainLoop() ;
  609.   return 0;
  610. }
  611.  
  612.   
  613.  
  614.